<style scoped>
.outer--{width: 650px;padding: 04px;border-radius: 04px;border: solid 01px var(--color-bg);outline: 0;}
.outer{outline: 0;}
.outer .editor-inner{display: block;width: 100%;height: 600px;outline: none;resize: none;overflow-y: scroll;}
.outer .editor-inner::-webkit-scrollbar{display: none;}
</style>
<template>
  <van-field v-bind="$attrs"
             :readonly="is_info"
             :placeholder="placeholder"
             :name="is_info?'':name"
             :model-value="modelValue" >
    <template #input>
      <div v-if="is_info" v-html="modelValue"></div>
      <div v-else class="outer">
        <input type="file" style="display: none" ref="input_file" accept="image/*" @change="upload_img">
        <textarea class="editor-inner" ref="editor" spellcheck="false" :name="name" :value="modelValue"></textarea>
      </div>
    </template>
  </van-field>
</template>

<script>
import s94EditorMjs from 's94-editor'
import {img_handle} from "@/js/s94_tool.js";
import {msg} from "@/js/vant_tool.js";
import {file_upload} from "@/js/api_tool.js";

export default {
  name: "editor",
  props: {
    name: String,
    modelValue: [String,Number],
    config: [String,Object],
    placeholder: String,
    is_info: Boolean,
  },
  emits: ['update:modelValue','change'],
  data(){
    return {
      need_display: true, //定义当modelValue变动时是否需要渲染，用来阻止当前组件变动 modelValue 后重新渲染

      editor: null,
      upload_img_callback: null,
      upload_ing: false,
    }
  },
  methods: {
    upload_img(e){
      if (typeof this.upload_img_callback !== 'function') return;
      if (this.upload_ing) return msg('上传中，请稍后！');
      let dom = e.target;
      let file = dom.files[0];
      if (!file) return msg('选择文件不存在');
      dom.value = '';
      (new Promise((resolve)=>{
        if (!~['image/jpeg','image/png'].indexOf(file.type)) return resolve(file);
        img_handle(file, {width:2000, height:2000, fit:'scale-down', blank:'cut', to:'blob'}).then(blob=>{
          file = new File([blob], file.name, {type: blob.type});
          resolve(file);
        })
      })).then((file)=>{
        file_upload(file).then((data)=>{
          if (typeof this.upload_img_callback !== 'function') return;
          this.upload_img_callback(data.url);
        }).catch((e)=>{
          msg(e.message);
        })
      })
    },
    display(){
      let app = this;
      let editor_config = {
        image_callback(menu){
          return new Promise((resolve)=>{
            app.$refs.input_file.click();
            app.upload_img_callback = resolve;
          })
        },
      };
      if (this.config){
        editor_config.menus = this.config.toString().split(',')
      }
      this.editor = new s94EditorMjs(this.$refs.editor, editor_config);

      this.editor.container.addEventListener('input', ()=>{
        this.update_value(this.editor.html());
      });
      this.editor.textarea.addEventListener('change', ()=>{
        this.update_value(this.editor.html());
      });
    },
    update_value(value, need_display){
      if (!need_display){
        this.need_display = false;
        setTimeout(()=>{this.need_display = true;},5)
      }
      this.$emit('update:modelValue', value);
      this.$emit('change', value);
    },
  },
  watch: {
    config(v){
      this.display();
    },
    modelValue(){
      if (!this.need_display || !this.editor) return;
      setTimeout(()=>{
        this.editor.updateHtml();
        this.editor.lastRow();
      },5)
    },
  },
  computed: {},
  mounted() {
    this.display();
  }
}
</script>